package listeners.action;

import components.JStyleButton;
import containers.GamePanel;
import containers.RankPanel;
import containers.StartPanel;
import containers.WordleFrame;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
 * Title:        GlobalActionListener.java
 * Copyright:    Copyright(c) 2022
 *
 * @author Zhiye Huang
 * @version 1.0
 * @description A listener for global operations, like switch panels to be displayed.
 **/
public class GlobalActionListener implements ActionListener {
    private final WordleFrame frame;
    private JPanel active, tobeActive;
    private StartPanel startPanel;
    private GamePanel gamePanel;
    private RankPanel rankPanel;

    /**
     * Generator to get the frame to listen
     * @param frame in this program is always WordleFrame
     */
    public GlobalActionListener(WordleFrame frame) {
        this.frame = frame;
        initialise();
    }

    /**
     * Initialise the instance
     */
    public void initialise() {
        this.startPanel = frame.getStartPanel();
        this.gamePanel = frame.getGamePanel();
        this.rankPanel = frame.getRankPanel();
        this.active = startPanel;

        // Add all button to the GlobalActionListener
        addPanelBtn(startPanel.getCenterPanel().getComponents());
        addPanelBtn(gamePanel.getNorthPanel().getComponents());
        addPanelBtn(rankPanel.getComponents());
    }

    /**
     * Adding GlobalActionListener to JButtons through array of components from panels.
     * @param components Array of components from panels.
     */
    public void addPanelBtn(Component[] components) {
        for (Component component : components) {
            if (component.getClass() == JButton.class || component.getClass() == JStyleButton.class) {
                ((JButton) component).addActionListener(this);
            }
        }
    }

    /**
     * Change the panel to the frame.getGamePanel().
     */
    public void openSubPanel() {
//        frame.getStartPanel().setVisible(false);
//        frame.setContentPane(frame.getGamePanel());
//        frame.getGamePanel().setVisible(true);
//        frame.getGamePanel().requestFocusInWindow();
        active.setVisible(false);
        frame.setContentPane(tobeActive);
        active = tobeActive;
        active.setVisible(true);
        active.requestFocusInWindow();
        if (active.getClass() == gamePanel.getClass()) {
            gamePanel.setBegin(System.currentTimeMillis());
            System.out.println("Start.");
        }
        if (active.getClass() == startPanel.getClass()) {
            System.out.println("Back to the start panel");
        }
    }

    /**
     * End the program.
     */
    public void gameExit() {
        System.out.println("Exit.");
        System.exit(0);
    }

    /**
     * Method to return to the main frame.
     */
    public void backToStartPanel() {
        tobeActive = startPanel;
        openSubPanel();
    }

    /**
     * Deal with the change of display panel.
     * @param e the event to be processed
     */
    @Override
    public void actionPerformed(ActionEvent e) {

        // If pressed start button in StartPanel
        if (e.getSource() == startPanel.getStartBtn()) {
            tobeActive = gamePanel;
            openSubPanel();
        }

        if (e.getSource() == startPanel.getRankBtn()) {
            tobeActive = rankPanel;
            openSubPanel();
        }

        // If pressed exit button in StartPanel
        if (e.getSource() == startPanel.getExitBtn()) {

            // A dialog to decide exit or not
            int choice = JOptionPane.showConfirmDialog(startPanel, "Do you confirm to exit?", "EXIT",
                    JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
            if (choice == 0) {
                gameExit();
            }
        }

        // // If pressed back button in GamePanel
        if (e.getSource() == gamePanel.getBackBtn()) {
            tobeActive = startPanel;
            openSubPanel();
        }

        if (e.getSource() == rankPanel.getBackBtn()) {
            tobeActive = startPanel;
            openSubPanel();
        }
    }
}
